/*
 * Copyright (c) 2007 jNetX.
 * http://www.jnetx.com
 * All rights reserved.
 *
 * This software is the confidential and proprietary information of
 * jNetX. You shall not disclose such Confidential Information and
 * shall use it only in accordance with the terms of the license
 * agreement you entered into with jNetX.
 *
 * $Id$
 */
package com.jnetx.javax.sip.header;

import com.jnetx.javax.sip.util.ByteArrayUtil;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import java.text.ParseException;

/**
 * @author <a href="mailto:dparhonin@jnetx.ru">Dmitry Parhonin</a>
 * @version $Revision$
 */
public class AuthenticationInfoHeaderParser extends HeaderParserBase<AuthenticationInfoHeaderImpl> {
    private static final Log logger = LogFactory.getLog(AuthenticationInfoHeaderParser.class);

    protected Log getLogger() {
        return logger;
    }

    public final AuthenticationInfoHeaderImpl createLazily(byte[] data, int start, int end) {
        return new AuthenticationInfoHeaderImpl(data, start, end);
    }

    public AuthenticationInfoHeaderImpl[] parse(AuthenticationInfoHeaderImpl header, byte[] data, int start, int end) throws ParseException {
        if (header == null) header = new AuthenticationInfoHeaderImpl();
        int startOfData = start;
        //Number of parts of the header value which can be translated into separate headers of the same type.
        while (startOfData < end) {
            startOfData = ByteArrayUtil.firstMissing(data, ' ', startOfData, end);
            if (startOfData == -1)
                fail("Cannot parse the header!", start);
            int endOfPart = ByteArrayUtil.firstOccurence(data, ',', startOfData, end);
            if (endOfPart == -1)
                endOfPart = end;
            final int eqPosition = ByteArrayUtil.firstOccurence(data, '=', startOfData, endOfPart);
            if (eqPosition == -1)
                fail("Cannot parse authentication info!", startOfData);
            final String parName = new String(data, startOfData, eqPosition - startOfData);
            final int startOfValue = ByteArrayUtil.firstMissing(data, '"', eqPosition+1, endOfPart);
            final int endOfValue = ByteArrayUtil.lastMissing(data, '"', startOfValue, endOfPart);
            final String parValue = new String(data, startOfValue, endOfValue - startOfValue + 1);
            if (parName.equals("nextnonce"))
                header.setNextNonce(parValue);
            else if (parName.equals("qop"))
                header.setQop(parValue);
            else if (parName.equals("rspauth"))
                header.setResponse(parValue);
            else if (parName.equals("cnonce"))
                header.setCNonce(parValue);
            else if (parName.equals("nc")) {
                try {
                    header.setNonceCount(Integer.parseInt(parValue));
                } catch (Exception ex) {
                    throw new ParseException("Cannot parse nc parameter!", startOfValue);
                }
            }
            startOfData = endOfPart + 1;
        }
        return new AuthenticationInfoHeaderImpl[]{header};
    }
}
/*
 * $Log$
 */